<?php
/**
* This file goes hand in hand with the FQDN.class.php, It won't do much until you have a FQDN selected, more than likely
* this should be an extension of FQDN. In the rewrite we'll see. 
*
* $Id: Records.class.php 37 2005-04-03 05:54:36Z vluther $ 				
* @package includes
* @version $Rev: 37 $
* @copyright Copyright &copy; 2000-2007, Linuxpowered, Inc               
* @author Vidyut Luther <vid@linuxpowered.com> 
**/

/**
 * The DNS Record Class. 
 *
 */
class DNSRecord {
	
	/**#@+
	 * @access public
	 * @var mixed
	 */
	var $_strId ; 
	var $_strType ; 
	var $_strPriority; 
	var $_strHostname; 
	var $_strIp ; 
	/**
	 * The Master table. 
	 *
	 * @var string
	 * @access private
	 */
	var $_strMasterTable ; 
	
	
/*	This is the constructor of the Class
 *
 * @access public
 * @return boolean
 */	
	function DNSRecord()
	{
		// Set some Constants 
		$this->_strMasterTable = "rectypes"; 
		$this->_strId = null ; 
		$this->_strType = null ; 
		$this->_strPriority = null ; 
		$this->_strHostname = null ; 
		$this->_strIp = null ; 
		return true; 
	}
	
	/**
	 * Sets the Id of a record, useful when editing a record
	 *
	 * @param id
	 * @return void
	 */
	function mSetId($id)
	{
		$this->_strId = $id; 
	}
	
	/**#@+
	 * Basic Setters
	 * @param string $foo
	 * @access public
	 * @var string 
	 */
	function mSetType($type)
	{
		$this->_strType = $type; 
	}
	
	function mSetPriority($priority)
	{
		$this->_strPriority = $priority; 
	}
	
	function mSetHostName($hostname)
	{
		$this->_strHostname = $hostname ; 
	}

 	
	/**
	 * Sets the ip address for a record. Checks to see what type of ip address is being sent, if the address is a CNAME record,
	 * it does not need to match the perl formatting regular expression, but it does need to resolve to a real ip address.
	 * If the ip address is a properly formatted ip address, then we check to see if it is a valid ip address using MySQL's INET_ATON
	 * function. This function is called in the mIsValidIp method. 
	 *
	 * @param ip : The IP Address
	 * @param type : What type of Record this is an IP For. 
	 * @return unknown
	 */
	 
	 // This function needs a proper rewrite.. was I high when I wrote this ?
	function mSetIp($ip,$type="A")
	{
    
		$err = new ErrorHandler(); 
		$ip = rtrim($ip); // Remove whitespace from the right
		$ip = ltrim($ip); // Remove whitespace from the left

		// This regex checks if the format of the ip address is right. 
		if(preg_match("/\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/",$ip)) {
			// Now get the MYSQL Integer value of the ip address.
			$intIp = $this->_ipToint($ip); 
		} else {
			$ipaddress = gethostbyname($ip); 
			// Since gethostbyname doesn't give a proper error message, we need to get the integer value
			// of the ip address. 
			$intIp = $this->_ipToint($ipaddress);
		}
		
		switch($type) {
			case 'MX':
				
				$this->_strIp = $ip; 
				break;
			case 'CNAME':
				if(!is_null($intIp)) {
					$this->_strIp = $ip; 
				} else {
					$msg = "The ip address $ip. Is not a Valid Ip <BR> "; 
					$err->mDisplayError($msg,$code,$isFatal);
      				return false; 
				}
				break;
			default:
				if(!is_null($intIp)) {
					$this->_strIp = $intIp; 
				} else {
					$msg = "The ip address $ip. Is not a Valid Ip <BR> "; 
					$err->mDisplayError($msg,$code,$isFatal);
      				return false; 
				}
				break;
		}
	
		return true;

	}

/**
 * Validates an IP address to make sure it follows the 3 digit, less than 255 requirement for a proper ip address, 
 * if the ip address is 278.127.0.0 will meet the perl regular expression above, but will fail this check... method needs to be renamed
 *
 * @param ip
 * @return string 
 */

  function mValidateIp($ip) 
  {
 	$err =& new ErrorHandler(); 

    global $db; 
    $sql = "SELECT INET_ATON('$ip') AS validip"; 
    $rs = $db->mRun($sql); 
    $row=mysql_fetch_assoc($rs); 
    $ip = $row['validip']; 
  	
 
    if(!is_null($ip)) {
    	return $ip; 
    } else {
 		$msg = "The ip address $ip. Is not a Valid Ip <BR> "; 
		$err->mDisplayError($msg,$code,$isFatal);
      	return false; 
    }
  }

  /**
   * makes sure the MX record requested is a valid address. 
   *
   * @param mailhost
   * @return void
   */
  function setMXRecord($mailhost)
  {
  	// Check to see if the mailhost is resolvable, and if the ip address is a valid ip address just like setIp
  	global $db; 
  	$ipaddress = gethostbyname($mailhost); 
    
  	// If the ip is not a valid ip.. then do some more checks. 
  	if(!$this->_ipToint($ipaddress)) {
  		$fqdnid = $this->_strId; 
  		// Now make sure the ip says, hostname.FQDN. 
  		$fsql = "SELECT fqdn FROM fqdn WHERE fqdnid = '$fqdnid' "; 
  		$rs = $db->mRun($fsql);
			while($row=mysql_fetch_assoc($rs)) {
				$fqdn = $row['fqdn']; 
			}
  		
			// Replace the FQDN from the full ip, so we just have the first part. 
		
			$hostname = str_replace('.'.$fqdn,'',$mailhost); 
		
			$hostname = preg_replace('/\.$/','',$hostname) ; 
			// See if there is an A record or CNAME as this mailhost. 
 			
  		$sql = "SELECT * FROM records WHERE fqdnid = '$fqdnid' AND rtype IN ('A','CNAME') AND hostname='$hostname' "; 
  		echo $sql ."\n"; 
      $db->mRun($sql); 
  		$nr = $db->_NumRows; 
  		
  		if($nr > 0) {
  			// If a record was found, then that means a CNAME or A Record already exists, but dns hasn't taken over yet. 
  			// The MX record is A ok.. return true so an IP address can be set. 
  			
  			
				
  			$mailhost = $hostname . ".". $fqdn . "."; 
  			$this->_strIp =  $mailhost; 
  			
  			return true; 
  		} else {
  			$err =& new ErrorHandler(); 
  			$code = "1001"; 
  			
  			$msg = "($code) : The MX Record ($mailhost for $fqdn) could not be resolved, and NO A or CNAME record for it was found.<BR> \n";
        
        echo $msg; die;  
  			$err->mDisplayError($msg,$code,$isFatal);
      		return false; 
  		}
  		
  	} else { // If the hostname resolved... 
  		$this->_strIp = $mailhost; 
  		return true; 
  	}
  		
   
  	
  }
  
  
/**
 * Gets the MySQL integer value for an ip address. If the ip address is messed up, return is null 
 *
 * @param ip
 * @return int
 */

  	function _ipToint($ip)
  	{
  		global $db; 
  		$sql = "SELECT INET_ATON('$ip') AS validip"; 
  		$rs = $db->mRun($sql); 
    	$row=mysql_fetch_assoc($rs); 
    	$ip = $row['validip']; 
  		
    	if(!is_null($ip)) {
			  #echo "Valid IP Found \n"; 
    		return $ip; 
    	} else {
      		return false; 
    	}
  	}	
	
 /**
  * Load the different type of Records one can have. 
  * @return unknown
  * @desc Returns distinct types of Records available to the dns manager
  */
	function mLoadTypes() 
	{
	
		global $db ; 
		$table = $this->_strMasterTable ; 
		$sql = "SELECT DISTINCT(rtype),rname from $table "; 
		
		
		$rs = $db->mRun($sql); 
		$arrTypes = ""; 
		while($row=mysql_fetch_assoc($rs)) {
			$types = $row[rtype] ;
      $rname = $row['rname']; 
			$arrTypes[$types] = $row[rname] ; 
		}
		
		return $arrTypes; 
	}
	
	
	/**
	* Load the Hostnames assosicated with a domain name
	* @return array
	* @desc Returns all the records available by type for the specific domain we're looking at.
	*/
	function mLoadRecords()
	{
		$arrRecords = ""; 
		/* If the Id is not Set Error Out */
		if(is_null($this->_strId)) { 
			echo "Cannot figure out what domain to load records for ! <BR>"; 
			return false; 
		} else {
			global $db; 
			$fqdnid = $this->_strId ; 
		#	$sql = "select record_id,rtype,hostname,hostip,priority FROM records where fqdnid='$fqdnid' ORDER BY rtype"; 
		
      $sql = "select record_id,rtype,hostname,priority,CASE WHEN rtype IN ('CNAME','MX') THEN hostip ELSE INET_NTOA(hostip) END AS hostip	FROM records WHERE fqdnid='$fqdnid'  ORDER BY hostname "; 
      $rs = $db->mRun($sql); 
	
      $nr = $db->mGetNumRows(); 
      if($nr == 0) {
        return 0;
        exit;  
      } 
	    while($row=mysql_fetch_assoc($rs)) {
  			#$type = $row['rtype'];   
        #$hostip = $row['hostip'] ;
      	$arrRecords[] = $row; 	
			}
		
			return $arrRecords; 
		}
	}
	



/**
 * loadNameServers: Loads All name servers for the specific domain. If none found, return the results from the configuration.
 * @param none
 * 
 * @return string 
 * @access public 
 **/
  function loadNameServers()
  {
		if(is_null($this->_strId)) { 
			echo "Cannot figure out what domain to load records for ! <BR>"; 
			return false; 
		} else {
			global $db; 
			$fqdnid = $this->_strId ; 
		
      $sql = "select record_id,rtype,hostname,hostip	FROM records WHERE fqdnid='$fqdnid' AND rtype='NS' ";
      
      $rs = $db->mRun($sql);
      $strNS = '';  
      $nr = $db->_NumRows ;
			if($nr > 0) {
        while($row=mysql_fetch_assoc($rs)) {
			    $strNS .= "\t\t IN NS ". $row['hostname'] . ".\n"; 
        }
      } else {
        // Get the nameservers from the global configuration and apply them
        $nsql = "SELECT primary_dns,secondary_dns,tertiary_dns FROM binder_config"; 
        $nrs = $db->mRun($nsql); 
        while($nrow=mysql_fetch_assoc($nrs)) {
          if(!empty($nrow['primary_dns'])) {
            $defaultns[0] = $nrow['primary_dns']; 
          }

          if(!empty($nrow['secondary_dns'])) {
            $defaultns[1] = $nrow['secondary_dns'];
          }

          if(!empty($nrow['tertiary_dns'])) {
            $defaultns[2] = $nrow['tertiary_dns'];
          }
          
        }
        for($i=0; $i<count($defaultns); $i++) {
          $strNS .= "\t\t IN NS ". $defaultns[$i] . ".\n";  
        }
      }
		}

		    return $strNS ;  
  }
	
  
  
  
  
function mInsert()
{
		global $db ; 
		$hostname = $this->_strHostname ; 
		$ipaddr = $this->_strIp; 
		$fqdnid = $this->_strId ; 
		$type = $this->_strType ; 
		$priority = $this->_strPriority; 
		
		$insert = "INSERT INTO records (rtype,hostname,hostip,fqdnid,priority) VALUES "; 
		$values = "('$type','$hostname','$ipaddr','$fqdnid','$priority') "; 
	
    echo $values . "<BR> "; 
		$sql = $insert . $values ; 
		
		
		$db->mInsert($sql) ; 
	}


  /**
   * Update a Record for the domain
   *
   * @access public
   * @return boolean
   */
  function mUpdate()
  {
		global $db ; 
		$hostname = $this->_strHostname ; 
		$ipaddr = $this->_strIp; 
		$record_id = $this->_strId ; 
		$type = $this->_strType ; 
		$priority = $this->_strPriority; 
		

    $update = "UPDATE records SET rtype='$type',hostname='$hostname',hostip='$ipaddr',priority='$priority'"; 
    $where = " WHERE record_id='$record_id'"; 
    
		
		$sql = $update . $where; 
	
		$db->mInsert($sql) ; 
		return true; 
	}




/**
 * mLoadRecordsById: Loads Record by Record ID. (Usually, just one row). 
 * 
 * @return : array 
 * @access : public 
 **/
  function mLoadRecordsById()
	{
		$arrRecords = ""; 
		/* If the Id is not Set Error Out */
  
		if(is_null($this->_strId)) { 
			echo "Cannot figure out what domain to load records for ! <BR>"; 
			return false; 
		} else {
			global $db; 
			$fqdnid = $this->_strId ; 
			#$sql = "select record_id,rtype,hostname,INET_NTOA(hostip) AS hostip,priority FROM records where record_id='$fqdnid' ORDER BY rtype"; 
		  $sql = "select record_id,rtype,hostname,priority,CASE WHEN rtype='CNAME' OR rtype='MX' THEN hostip ELSE INET_NTOA(hostip) END AS hostip	FROM records WHERE record_id='$fqdnid' ORDER BY rtype "; 

    	
    	$rs = $db->mRun($sql); 
			
      while($row=mysql_fetch_assoc($rs)) {
				$arrRecords[] = $row; 	
			}
			
			return $arrRecords; 
		}
		
		
	}














  
}


?>
